﻿using System;
using System.IO;
using GeoAPI.Geometries;
using NetTopologySuite.Algorithm;
using NetTopologySuite.Utilities;

namespace NetTopologySuite.GeometriesGraph
{
	public class EdgeEnd : IComparable<EdgeEnd>
	{
		protected EdgeEnd(Edge edge)
		{
			this.Edge = edge;
		}

		public EdgeEnd(Edge edge, Coordinate p0, Coordinate p1) : this(edge, p0, p1, null)
		{
		}

		public EdgeEnd(Edge edge, Coordinate p0, Coordinate p1, Label label) : this(edge)
		{
			this.Init(p0, p1);
			this._label = label;
		}

		protected void Init(Coordinate p0, Coordinate p1)
		{
			this._p0 = p0;
			this._p1 = p1;
			this._dx = p1.X - p0.X;
			this._dy = p1.Y - p0.Y;
			this._quadrant = QuadrantOp.Quadrant(this._dx, this._dy);
			Assert.IsTrue(this._dx != 0.0 || this._dy != 0.0, "EdgeEnd with identical endpoints found");
		}

		public Edge Edge { get; protected set; }

		public Label Label
		{
			get
			{
				return this._label;
			}
			protected set
			{
				this._label = value;
			}
		}

		public Coordinate Coordinate
		{
			get
			{
				return this._p0;
			}
		}

		public Coordinate DirectedCoordinate
		{
			get
			{
				return this._p1;
			}
		}

		public int Quadrant
		{
			get
			{
				return this._quadrant;
			}
		}

		public double Dx
		{
			get
			{
				return this._dx;
			}
		}

		public double Dy
		{
			get
			{
				return this._dy;
			}
		}

		public Node Node { get; set; }

		public int CompareTo(EdgeEnd e)
		{
			return this.CompareDirection(e);
		}

		public int CompareDirection(EdgeEnd e)
		{
			if (this._dx == e._dx && this._dy == e._dy)
			{
				return 0;
			}
			if (this._quadrant > e._quadrant)
			{
				return 1;
			}
			if (this._quadrant < e._quadrant)
			{
				return -1;
			}
			return CGAlgorithms.ComputeOrientation(e._p0, e._p1, this._p1);
		}

		public virtual void ComputeLabel(IBoundaryNodeRule boundaryNodeRule)
		{
		}

		public virtual void Write(StreamWriter outstream)
		{
			double num = Math.Atan2(this._dy, this._dx);
			string fullName = base.GetType().FullName;
			int num2 = fullName.LastIndexOf('.');
			string text = fullName.Substring(num2 + 1);
			outstream.Write(string.Concat(new object[]
			{
				"  ",
				text,
				": ",
				this._p0,
				" - ",
				this._p1,
				" ",
				this._quadrant,
				":",
				num,
				"   ",
				this._label
			}));
		}

		public override string ToString()
		{
			double num = Math.Atan2(this._dy, this._dx);
			string name = base.GetType().Name;
			return string.Concat(new object[]
			{
				"  ",
				name,
				": ",
				this._p0,
				" - ",
				this._p1,
				" ",
				this._quadrant,
				":",
				num,
				"   ",
				this._label
			});
		}

		private Label _label;

		private Coordinate _p0;

		private Coordinate _p1;

		private double _dx;

		private double _dy;

		private int _quadrant;
	}
}
